#pragma once

#include "CoreMinimal.h"
#include "UObject/Object.h"
#include "ServiceBase.generated.h"

UCLASS()
class SERVICEMODULE_API UServiceBase : public UObject
{
	GENERATED_BODY()

public:
	template <typename T>
	static FString GetClassName()
	{
		return FString(typeid(T).name());
	}
	
	template <typename T>
	static T* Register()
	{
		static_assert(TIsDerivedFrom<T, UServiceBase>::IsDerived, "T must inherit from UObjectSingleton");

		if (!T::Instance.IsValid())	//	Instance must be public
		{
			T::Instance = NewObject<T>(GetTransientPackage(), NAME_None);
			T::Instance->AddToRoot(); // Prevent garbage collection
		}
		return T::Instance.Get();
	}

	template <typename T>
	static void Unregister()
	{
		static_assert(TIsDerivedFrom<T, UServiceBase>::IsDerived, "T must inherit from UObjectSingleton");

		if (T::Instance.IsValid())
		{
			FString ClassName = GetClassName<T>();
			UE_LOG(LogTemp, Display, TEXT("Remove Service: %s"), *ClassName)
			
			T::Instance->RemoveFromRoot(); // Allow garbage collection
			// T::Instance->ConditionalBeginDestroy(); TODO: maybe immediately start garbage collection 
			T::Instance = nullptr;
		}
	}
};